package com.swang.redis.service.handler;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName: RedisService
 * @Description: redis服务接口
 * @author swang
 * @date 2017年4月23日 下午6:41:29
 */
public interface RedisService {
	/**
	 * @Description: Hash（哈希表） ： 将哈希表 key 中的域 field 的值设为 value 。 如果 key
	 *               不存在，一个新的哈希表被创建并进行 HSET 操作 如果域 field 已经存在于哈希表中，旧值将被覆盖。
	 * @param key
	 * @param hashKey
	 * @param value
	 * @Date: 2016年3月14日 上午11:16:06
	 */
	void hSet(final String key, String hashKey, Object value);

	/**
	 * @Description: Hash（哈希表） ： 返回哈希表 key 中给定域 field 的值。
	 * @param key
	 * @param field
	 * @Date: 2016年3月14日 上午11:16:27
	 */
	Object hGet(final String key, String field);

	/**
	 * @Description: Hash（哈希表） ： 同时将多个 field-value (域-值)对设置到哈希表 key 中。
	 *               此命令会覆盖哈希表中已存在的域。 如果 key 不存在，一个空哈希表被创建并执行 HMSET 操作。
	 * @param key
	 * @param map
	 * @Date: 2016年3月14日 上午11:16:19
	 */
	void hMSet(final String key, Map<String, Object> map);

	/**
	 * @Description: Hash（哈希表） ： 返回哈希表 key 中，一个或多个给定域的值。 如果给定的域不存在于哈希表，那么返回一个
	 *               nil 值。
	 * @param key
	 * @param fields
	 * @Date: 2015年11月14日 下午2:49:39
	 */
	List<Object> hMGet(final String key, Collection<Object> fields);

	/**
	 * @Description: Hash（哈希表） ： 返回哈希表 key 中，所有的域和值。 在返回值里，紧跟每个域名(field
	 *               name)之后是域的值(value)，所以返回值的长度是哈希表大小的两倍。
	 * @param key
	 * @Date: 2016年3月14日 上午11:16:34
	 */
	Map<Object, Object> hGetAll(final String key);

	/**
	 * @Description: Hash（哈希表） ： 返回哈希表 key 中所有域的值。
	 * @param key
	 * @Date: 2015年11月14日 下午2:56:59
	 */
	List<Object> hVals(final String key);

	/**
	 * @Description: Hash（哈希表） ： 查看哈希表 key 中，给定域 field 是否存在。
	 * @param key
	 * @param field
	 * @Date: 2016年3月14日 上午11:16:43
	 */
	Boolean hExists(final String key, Object field);

	/**
	 * @Description: Hash（哈希表） ： 删除哈希表 key 中的一个或多个指定域，不存在的域将被忽略。
	 * @param key
	 * @param ojbKeys
	 * @Date: 2016年3月14日 上午11:16:50
	 */
	void hDel(final String key, Object... ojbKeys);

	/**
	 * @Description: Hash（哈希表） ： 返回key 中域的数量
	 * @param key
	 * @Date: 2015年11月14日 下午2:53:33
	 */

	Set<Object> hKeys(final String key);

	/**
	 * @Description: Hash（哈希表） ： 返回哈希表 key 中域的数量
	 * @param key
	 * @Date: 2015年11月14日 下午2:53:33
	 */
	Long hLen(final String key);

	/**
	 * @Description: String（字符串） ： 返回 key 所关联的字符串值。 如果 key 不存在那么返回特殊值 nil 。 假如
	 *               key 储存的值不是字符串类型，返回一个错误，因为 GET 只能用于处理字符串值。
	 * @param key
	 * @return 当 key 不存在时，返回 nil ，否则，返回 key 的值。如果 key 不是字符串类型，那么返回一个错误。 @ update
	 * @Date: 2016年3月14日 上午11:16:56
	 */
	String get(final String key);

	/**
	 * @Description: String（字符串） ： 返回 key 中字符串值的子字符串，字符串的截取范围由 start 和 end
	 *               两个偏移量决定(包括 start 和 end 在内)。 负数偏移量表示从字符串最后开始计数， -1 表示最后一个字符，
	 *               -2 表示倒数第二个，以此类推。 getRange
	 *               通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求
	 * @param key
	 * @param start
	 * @param end
	 * @Date: 2015年11月14日 下午3:29:18
	 */
	String getRange(final String key, long start, long end);

	/**
	 * @Description: String（字符串） ： 将给定 key 的值设为 value ，并返回 key 的旧值(old value)。
	 * @param key
	 * @param value
	 * @return 返回给定 key 的旧值。当 key 没有旧值时，也即是， key 不存在时，返回 nil 。 @ update Author:
	 * @Date: 2015年11月14日 下午3:31:15
	 */
	String getSet(final String key, String value);

	/**
	 * @Description: String（字符串） ： 将字符串值 value 关联到 key 如果 key 已经持有其他值， SET
	 *               就覆写旧值，无视类型。
	 * @param key
	 * @param value
	 * @Date: 2016年3月14日 上午11:17:03
	 */
	void set(final String key, String value);

	/**
	 * @Description: String（字符串） ： 将字符串值 value 关联到 key ，并设置生命周期，以秒为单位
	 *               对于某个原本带有生存时间（TTL）的键来说， 当 SET 命令成功在这个键上执行时， 这个键原有的 TTL 将被清除。
	 * @param key
	 * @param value
	 * @param seconds
	 * @Date: 2016年3月14日 上午11:17:12
	 */
	void set(final String key, String value, int seconds);

	/**
	 * @Description: String（字符串） ： 如果 key 已经存在并且是一个字符串， APPEND 命令将 value 追加到 key
	 *               原来的值的末尾。 如果 key 不存在， APPEND 就简单地将给定 key 设为 value ，就像执行 SET
	 *               key value 一样。
	 * @param key
	 * @param value
	 * @Date: 2015年11月14日 下午3:34:29
	 */
	Integer append(final String key, String value);

	/**
	 * @Description: List（列表） ： 将一个或多个值 value 插入到列表 key 的表头 如果有多个 value 值，那么各个
	 *               value 值按从左到右的顺序依次插入到表头： 比如说，对空列表 mylist 执行命令 LPUSH mylist a
	 *               b c ，列表的值将是 c b a ， 这等同于原子性地执行 LPUSH mylist a 、 LPUSH
	 *               mylist b 和 LPUSH mylist c 三个命令。 如果 key 不存在，一个空列表会被创建并执行
	 *               LPUSH 操作。
	 * @param key
	 * @param value
	 * @Date: 2016年3月14日 上午11:17:21
	 */
	Long lPush(final String key, String... values);

	/**
	 * @Description: List（列表） ： 将一个或多个值 value 插入到列表 key 的表头 如果有多个 value 值，那么各个
	 *               value 值按从左到右的顺序依次插入到表头： 比如说，对空列表 mylist 执行命令 LPUSH mylist a
	 *               b c ，列表的值将是 c b a ， 这等同于原子性地执行 LPUSH mylist a 、 LPUSH
	 *               mylist b 和 LPUSH mylist c 三个命令。 如果 key 不存在，一个空列表会被创建并执行
	 *               LPUSH 操作。
	 * @param key
	 * @param values
	 * @Date: 2015年11月14日 下午3:16:44
	 */
	Long lPush(final String key, Collection<String> values);

	/**
	 * @Description: List（列表） ： 移除并返回列表 key 的头元素。
	 * @param key
	 * @Date: 2016年3月14日 上午11:17:40
	 */
	String lPop(final String key);

	/**
	 * @Description: List（列表） ： 将一个或多个值 value 插入到列表 key 的表尾(最右边)。 如果有多个 value
	 *               值，那么各个 value 值按从左到右的顺序依次插入到表尾：比如对一个空列表 mylist 执行 RPUSH
	 *               mylist a b c ， 得出的结果列表为 a b c ， 等同于执行命令 RPUSH mylist a 、
	 *               RPUSH mylist b 、 RPUSH mylist c 。 如果 key 不存在，一个空列表会被创建并执行
	 *               RPUSH 操作。
	 * @param key
	 * @param values
	 * @Date: 2015年11月14日 下午3:14:16
	 */
	Long rPush(final String key, String... values);

	/**
	 * @Description: List（列表） ： 将一个或多个值 value 插入到列表 key 的表尾(最右边)。 如果有多个 value
	 *               值，那么各个 value 值按从左到右的顺序依次插入到表尾：比如对一个空列表 mylist 执行 RPUSH
	 *               mylist a b c ， 得出的结果列表为 a b c ， 等同于执行命令 RPUSH mylist a 、
	 *               RPUSH mylist b 、 RPUSH mylist c 。 如果 key 不存在，一个空列表会被创建并执行
	 *               RPUSH 操作。
	 * @param key
	 * @param values
	 * @Date: 2015年11月14日 下午3:14:16
	 */
	Long rPush(final String key, Collection<String> values);

	/**
	 * @Description: List（列表） ： 移除并返回列表 key 的尾元素。
	 * @param key
	 * @Date: 2015年11月14日 下午3:12:07
	 */
	String rPop(final String key);

	/**
	 * @Description: List（列表） ： 返回列表 key 的长度。 如果 key 不存在，则 key 被解释为一个空列表，返回 0 .
	 * @param key
	 * @Date: 2016年3月14日 上午11:18:16
	 */
	Long lLen(final String key);

	/**
	 * @Description: List（列表） ： 返回列表 key 中指定区间内的元素，区间以偏移量 start 和 stop 指定。
	 *               下标(index)参数 start 和 stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1
	 *               表示列表的第二个元素，以此类推。 你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2
	 *               表示列表的倒数第二个元素，以此类推。
	 *               【注意LRANGE命令和编程语言区间函数的区别】假如你有一个包含一百个元素的列表，对该列表执行 LRANGE list
	 *               0 10 ，结果是一个包含11个元素的列表，这表明 stop 下标也在 LRANGE
	 *               命令的取值范围之内(闭区间)，这和某些语言的区间函数可能不一致， 比如Ruby的 Range.new 、
	 *               Array#slice 和Python的 range() 函数。 【超出范围的下标】超出范围的下标值不会引起错误。如果
	 *               start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大，那么 LRANGE
	 *               返回一个空列表。如果 stop 下标比 end 下标还要大，Redis将 stop 的值设置为 end 。
	 * @param key
	 * @param start
	 * @param stop
	 * @Date: 2016年3月14日 上午11:19:03
	 */
	List<String> lRange(final String key, int start, int stop);

	/**
	 * @Description: List（列表） ： 根据参数 count 的值，移除列表中与参数 value 相等的元素。 count
	 *               的值可以是以下几种： count > 0 : 从表头开始向表尾搜索，移除与 value 相等的元素，数量为 count
	 *               。 count < 0 : 从表尾开始向表头搜索，移除与 value 相等的元素，数量为 count 的绝对值。
	 *               count = 0 : 移除表中所有与 value 相等的值。
	 * @param key
	 * @param count
	 * @param value
	 * @return 被移除元素的数量,因为不存在的 key 被视作空表(empty list)，所以当 key 不存在时， LREM 命令总是返回 0
	 * @Date: 2016年3月14日 上午11:19:11
	 */
	Long lRem(final String key, long count, String value);

	/**
	 * @Description: List（列表）： 返回列表 key 中，下标为 index 的元素。 下标(index)参数 start 和
	 *               stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1 表示列表的第二个元素，以此类推。
	 *               你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推。 如果 key
	 *               不是列表类型，返回一个错误。
	 * @param key
	 * @param index
	 * @return 列表中下标为 index 的元素。 如果 index 参数的值不在列表的区间范围内(out of range)，返回 nil 。 @
	 * @Date: 2016年3月14日 上午11:19:18
	 */
	String lIndex(final String key, long index);

	/**
	 * @Description: List（列表）： 将列表 key 下标为 index 的元素的值设置为 value 。 当 index
	 *               参数超出范围，或对一个空列表( key 不存在)进行 LSET 时，返回一个错误。
	 * @param key
	 * @param index
	 * @param value
	 * @Date: 2016年3月14日 上午11:19:36
	 */
	void lSet(final String key, long index, String value);

	/**
	 * @Description: List（列表）:
	 *               对一个列表进行修剪(trim)，就是说，让列表只保留指定区间内的元素，不在指定区间之内的元素都将被删除。
	 *               举个例子，执行命令 LTRIM list 0 2 ，表示只保留列表 list 的前三个元素，其余元素全部删除。
	 *               下标(index)参数 start 和 stop 都以 0 为底，也就是说，以 0 表示列表的第一个元素，以 1
	 *               表示列表的第二个元素，以此类推。 你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2
	 *               表示列表的倒数第二个元素，以此类推。
	 * @param key
	 * @param start
	 * @param end
	 * @Date: 2016年3月14日 上午11:19:47
	 */
	void lTrim(final String key, long start, int end);

	/**
	 * @Description: Set（集合）： 将一个或多个元素加入到集合key中，已经存在于集合中的member元素将被忽略 假如 key
	 *               不存在，则创建一个只包含 member 元素作成员的集合。 当 key 不是集合类型时，返回一个错误。
	 * @param key
	 * @param values
	 * @Date: 2016年3月14日 上午11:25:06
	 */
	Long sAdd(final String key, String... values);

	/**
	 * @Description: Set（集合）： 移除并返回集合的一个随机元素，如果只想获取一个随机元素，但不想该元素从集合中被移除的话，可以使用
	 *               sRandMember()方法。
	 * @param key
	 * @Date: 2016年3月14日 上午11:30:34
	 */
	String sPop(final String key);

	/**
	 * @Description: Set（集合）： 如果命令执行时，只提供了 key 参数，那么返回集合中的一个随机元素。 如果 count
	 *               为正数，且小于集合基数，那么命令返回一个包含 count 个元素的数组，数组中的元素各不相同。如果 count
	 *               大于等于集合基数，那么返回整个集合。 如果 count
	 *               为负数，那么命令返回一个数组，数组中的元素可能会重复出现多次，而数组的长度为 count 的绝对值 该操作和 SPOP
	 *               相似，但 SPOP 将随机元素从集合中移除并返回，而 SRANDMEMBER
	 *               则仅仅返回随机元素，而不对集合进行任何改动。
	 * @param key
	 * @param count
	 * @Date: 2016年3月14日 上午11:35:46
	 */
	Set<String> sRandMember(final String key, long count);

	/**
	 * @Description: Set（集合）： 返回一个集合的全部成员，该集合是所有给定集合之间的差集。 不存在的 key 被视为空集。
	 * @param key
	 * @param otherKey
	 * @Date: 2016年3月14日 下午1:29:51
	 */
	Set<String> sDiff(final String key, String otherKey);

	/**
	 * @Description: Set（集合）： 这个命令的作用和 SDIFF 类似，但它将结果保存到 destination
	 *               集合，而不是简单地返回结果集。 如果 destination 集合已经存在，则将其覆盖。 destination
	 *               可以是 key 本身。
	 * @param key
	 * @param otherKey
	 * @param destKey
	 * @Date: 2016年3月14日 下午1:32:16
	 */
	Long sDiffStore(final String key, String otherKey, String destKey);

	/**
	 * @Description: Set（集合）： 这个命令的作用和 SDIFF 类似，但它将结果保存到 destination
	 *               集合，而不是简单地返回结果集。 如果 destination 集合已经存在，则将其覆盖。 destination
	 *               可以是 key 本身。
	 * @param key
	 * @param otherKey
	 * @param destKey
	 * @Date: 2016年3月14日 下午1:37:11
	 */
	Long sDiffStore(final String key, Collection<String> otherKey, String destKey);

	/**
	 * @Description: Set（集合）： 判断 member 元素是否集合 key 的成员
	 * @param key
	 * @param member
	 * @Date: 2016年3月14日 下午1:39:14
	 */
	Boolean sIsMember(final String key, Object member);

	/**
	 * @Description: Set（集合）： 返回集合 key 中的所有成员。 不存在的 key 被视为空集合。
	 * @param key
	 * @Date: 2016年3月14日 下午1:46:31
	 */
	Set<String> sMembers(final String key);

	/**
	 * @Description: Set（集合）： 将 member 元素从 source 集合移动到 destination 集合 如果 source
	 *               集合不存在或不包含指定的 member 元素，则 SMOVE 命令不执行任何操作，仅返回 0 。否则， member
	 *               元素从 source 集合中被移除，并添加到 destination 集合中去。 当 destination
	 *               集合已经包含 member 元素时， SMOVE 命令只是简单地将 source 集合中的 member 元素删除。
	 *               当 source 或 destination 不是集合类型时，返回一个错误。 如果 member 元素被成功移除，返回
	 *               1 。 如果 member 元素不是 source 集合的成员，并且没有任何操作对 destination
	 *               集合执行，那么返回 0 。
	 * @param key
	 * @param value
	 * @param destKey
	 * @Date: 2016年3月14日 下午1:50:50
	 */
	Boolean sMove(final String source, String member, String destination);

	/**
	 * @Description: Set（集合）： 移除集合 key 中的一个或多个 member 元素，不存在的 member 元素会被忽略。 当
	 *               key 不是集合类型，返回一个错误 返回被成功移除的元素的数量，不包括被忽略的元素。
	 * @param key
	 * @param values
	 * @Date: 2016年3月14日 下午1:54:59
	 */
	Long sRem(final String key, Object... values);
	
	/**
	 * @Description: Set（集合）： 返回集合 key 的基数(集合中元素的数量)。
	 * @param key
	 * @return @ update Author: shenls@hundsun.com
	 * @Date: 2016年11月3日 下午1:54:59
	 */
	Long sSCard(final String key);

	/**
	 * @Description: Key（键）: 删除给定的一个 key 。
	 * @param key
	 * @Date: 2016年3月14日 下午1:59:57
	 */
	void kDel(final String key);

	/**
	 * @Description: Key（键）: 删除给定的多个key
	 * @param keys
	 * @Date: 2016年3月14日 下午2:00:52
	 */
	void kDel(final Collection<String> keys);

	/**
	 * @Description: Key（键）: 为给定 key 设置生存时间，当 key 过期时(生存时间为 0 )，它会被自动删除。
	 *               对一个已经带有生存时间的 key 执行 EXPIRE 命令，新指定的生存时间会取代旧的生存时间。
	 * @param key
	 * @param seconds
	 * @Date: 2016年3月14日 下午2:04:10
	 */
	Boolean KExpire(final String key, int seconds);

	/**
	 * @Description: Key（键）: 检查给定 key 是否存在。 若 key 存在，返回 1 ，否则返回 0 。
	 * @param key
	 * @Date: 2016年3月14日 下午2:17:31
	 */
	Boolean kExists(final String key);

	/**
	 * @Description: Key（键）: 查找所有符合给定模式 pattern 的 key 。 ！禁止使用*符号直接匹配！ KEYS h?llo
	 *               匹配 hello ， hallo 和 hxllo 等。 KEYS h*llo 匹配 hllo 和 heeeeello
	 *               等。 KEYS h[ae]llo 匹配 hello 和 hallo ，但不匹配 hillo 。 特殊符号用 \ 隔开
	 * @param pattern
	 * @Date: 2016年3月14日 下午2:19:06
	 */
	Set<String> kKeys(final String pattern);

	Boolean setIfAbsent(String key, String timeMillisecond);

	String getAndSet(String key, String timeMillisecond);

	/**
	 * 
	 * @Title:incr
	 * @author 沈利松
	 * @Description:将 key 中储存的数字值增一. 如果 key 不存在，那么 key 的值会先被初始化为 0 ，然后再执行 INCR
	 *                操作。 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。 本操作的值限制在 64
	 *                位(bit)有符号数字表示之内。
	 * @date 2016年8月19日 上午8:44:05
	 * @parm:
	 * @return:Integer
	 * @throws:
	 */
	Long incr(String key);

	/**
	 * 
	 * @Title:incr
	 * @author 沈利松
	 * @Description:将 key 所储存的值加上增量 increment 。 如果 key 不存在，那么 key 的值会先被初始化为 0
	 *                ，然后再执行 INCRBY 命令。 如果值包含错误的类型，或字符串类型的值不能表示为数字，那么返回一个错误。
	 *                本操作的值限制在 64 位(bit)有符号数字表示之内。
	 * 
	 * @date 2016年8月19日 上午8:44:05
	 * @parm:
	 * @return:Integer
	 * @throws:
	 */
	Long incrBy(String key, Long value);

}
